/********************************************************************
 * Filename:	Commands.c
 * Description:  The commands used in the testing interface.
 * Group 2:		nachOS
 * Author(s):	Daniel Fairweather
 *             Ying Wang
 * Class:		CSE 325
 * Instructor:	David Duggan
 * Assignment:	Lab #6 Page Replacement
 * Assigned:	4/2/2013
 * Due:			4/9/2013
 ********************************************************************/



#include "Testing.h"

char buffer[100];

char* runCommand(char command[100], char args[2][100], int argc){
    /* TESTMODE */
    if(strcmp(command, "testmode") == 0 && argc == 1){
        if(strcmp(args[0], "dynamic") == 0){
            clearScreen();
            testMode = 0;
            return("TestMode set to Dynamic.");
        }
        else if(strcmp(args[0], "static") == 0){
            clearScreen();
            testMode = 1;
            return("TestMode set to Static.");
        }
        else if(strcmp(args[0], "redirect") == 0){
            //clearScreen();
            testMode = 2;
            return("TestMode set to Redirect.");
        }
        else{
            return("TestMode name is invalid.");
        }
    }
    
    
    /* CLEAR */
    else if(strcmp(command, "clear") == 0 && argc == 0){
        if(testMode == 0){
            return("Clear does not work in in dynamic test mode.");
        }
        else{
            clearScreen();
            return("Screen cleared. Except for this ;)");
        }
    }
   
    
    
    /* QUIT */
    else if((strcmp(command, "quit") == 0 || strcmp(command, "q") == 0 || strcmp(command, "exit") == 0) && argc == 0){
        exit(0);
    }
    
    
    
    /* INIT_MEM */
    else if(strcmp(command, "init_mem") == 0 && argc == 0){
        init();
        return("Initialized.");
    }
    
    
    
    /* ALLOC_PT */
    else if(strcmp(command, "alloc_pt") == 0 && argc == 1){
        int page_size = atoi(args[0]);
        int result = allocateFrames(page_size);
		
        if(result == -1){
            return("Cannot allocate an empty page table.");
        }
        else if(result == -2){
            return("Not enough space for a page table of the specified size.");
        }
        else if(result == -3){
            return("No remaining page tables (Reached limit of NUM_PAGETABLES).");
        }
        else{
			sprintf(buffer, "Page table allocated. Page Table ID: %i", result);
			return(buffer);
        }
    }
    
    
    
    /* DEALLOC_PT */
    else if(strcmp(command, "dealloc_pt") == 0 && argc == 1){
        int page_table_id = atoi(args[0]);
		int result;
		if(page_table_id >= 0 && page_table_id <= 99){
			result = deallocateTable(page_table_id);
		}
		else{
			result = -1;
		}
		


        if(result == 0){
            return("Page table deallocated.");
        }
        else if(result == -1){
            return("Invalid page table id.");
        }
    }
    
    
    
    /* PAGE_FAULT */
    else if(strcmp(command, "page_fault") == 0 && argc == 2){
        int page_table_id = atoi(args[0]);
        int page_number = atoi(args[1]);
        int result = pageFault(page_table_id, page_number);
        if(result == -2){
            return("The specified page is not in the given page table.");
        }
        else if(result == -1){
            return("The page is already loaded in RAM.");
        }
        else if(result == 0){
            return("Page loaded to RAM.");
        }
    }
    
	/* ACCESS */
    else if(strcmp(command, "access") == 0 && argc == 2){
        int page_table_id = atoi(args[0]);
        int page_number = atoi(args[1]);
        int result = access(page_table_id, page_number);
        if(result == -2){
            return("The specified page is not in the given page table.");
        }
        else if(result == 1){
            return("Page accessed. LRU Queue updated.");
        }
        else if(result == 0){
            return("Page not in RAM. Executed page fault.");
        }
    }
    
    /* LIST */
    else if(strcmp(command, "list") == 0 && (argc == 1 || argc == 0 || argc == 2)){
        int page_table_id;
        if(testMode == 0){
            return("The data structures are already listed! Try switching to static mode (testmode static).");
        }
        else if(strcmp(args[0], "user") == 0 && argc == 1){
            list_user();
        }
        else if(strcmp(args[0], "pagetable") == 0 && argc == 2 && -1 < atoi(args[1]) < 100){
			printf("\t\tLOGICAL PAGE\tPYHSICAL PAGE\tFRAME IN RAM\n");
            page_table_id = atoi(args[1]);
            list_pagetable(page_table_id);
        }
        else if(strcmp(args[0], "pagetable") == 0 && argc == 1){
            list_all_pagetables();
        }
        else if(strcmp(args[0], "system") == 0 && argc == 1){
            list_system();
        }
		else if(strcmp(args[0], "lru") == 0 && argc == 1){
			printLRUModule();
        }
        else if(argc == 0){
			printSystemDataStructureModule();
			printf("\n");
			printUserDataStructureModule();
			printf("\n");
			printLRUModule();
			printf("\n");
			printPageTablesModule();
        }
        else{
            return("Invalid arguments.");
        }
        return("\n");
    }
    
    
    
    /* BELOW IS A TEMPLATE FOR ADDING NEW COMMANDS. ADD THEM BETWEEN THE 'IF' at the top and the 'RETURN' at the bottom. */
    /*
     
     else if(strcmp(command, "mycommand") == 0 && argc == the_number_of_arguments){
     // Do something fancy...
     return("The result as a string.");
     }
     
     */
    
    
    /* Invalid command. */
    return("Invalid command or arguments.");
}